-
Notifications
You must be signed in to change notification settings - Fork 7
Partial expression evaluation, example of a builtin function #1115
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Partial expression evaluation, example of a builtin function #1115
Conversation
…e current structure causes circular import
…ontains cyclic imports but only runtime, never at init...)
0c0de3a
to
e9420d9
Compare
def evaluate( | ||
self, | ||
context: EvaluationContext, | ||
raise_error: bool = True, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
strict
has been renamed to raise_error
, feels more verbose.
force_evaluate
basically means that we don't evaluate blacklisted symbols at all, thus yielding "partial evaluation" that we needed.
As an example:
from flow360 import control, math
x = UserVariable(name="x", value = 1)
# Works with python
model.expression = math.cross([x, 2 * x, 1], control.machRef)
# Also works with strings...
model.expression = "math.cross([x, 2 * x, 1], control.machRef)"
# When converting to solver, cross is inlined:
# [
# (2 * x) * ((solution.coordinate)[2]) - (1 * ((solution.coordinate)[1])),
# 1 * ((solution.coordinate)[0]) - (x * ((solution.coordinate)[2])),
# x * ((solution.coordinate)[1]) - ((2 * x) * ((solution.coordinate)[0]))
# ]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I propose raise_error -> raise_on_non_evaluable
force_evaluate -> evaluate_numerically
something like these.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First one I agree with. For the second one I stand by force_evaluate
, because the flag changes the behavior on handling symbols that return False
for can_evaluate
(solver variables in our case), essentially forcing those symbols to be evaluated to a numeric value. I think evaluate_numerically
would fit if we changed evaluable
and can_evaluate
to something like numeric
and has_numeric_value
respectively.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed raise_error
to raise_on_non_evaluable
pattern = f"({'|'.join(escaped_delimiters)})" | ||
result = re.split(pattern, value) | ||
return [part for part in result if part != ""] | ||
def __soft_fail_sub__(self, other): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a port of #1092
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are we overloading enough operators?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we need to overload all binary operators that have a left and right version. I'll double check and write a test for it.
e9420d9
to
5e7e746
Compare
There are cyclic pylint errors. I have not got chance to take a look. |
Yup, in
|
if len(expr.elements) == 1: | ||
return f"{{{elements[0]}}}" | ||
return f"{{{', '.join(elements)}}}" | ||
return "std::vector<float>()" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am a bit confused. What is the use case of this? What expression would trigger this line?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe (,)
would being an empty tuple declaration. Considering we are not using it perhaps would be better to just disallow it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK changed to error for stricter checking
@@ -158,8 +157,8 @@ def _list(expr, syntax, name_translator): | |||
return f"[{elements_str}]" | |||
if syntax == TargetSyntax.CPP: | |||
if len(expr.elements) == 0: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here. Should we throw exception in this case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the general case its still a valid python syntax so it makes some sense to have this. It will just fail in the validator for any DimensionedType so technically it is never reached for our use cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK changed to error for stricter checking
|
||
force_evaluate (bool): If True, evaluate evaluable objects marked as | ||
non-evaluable, instead of returning their identifier. | ||
inline (bool): If True, inline certain marked function calls. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we still need this line?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whoops, nope. It's a leftover. Will remove.
145584b
to
00f639c
Compare
00f639c
to
1c67711
Compare
@@ -158,8 +157,8 @@ def _list(expr, syntax, name_translator): | |||
return f"[{elements_str}]" | |||
if syntax == TargetSyntax.CPP: | |||
if len(expr.elements) == 0: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK changed to error for stricter checking
if len(expr.elements) == 1: | ||
return f"{{{elements[0]}}}" | ||
return f"{{{', '.join(elements)}}}" | ||
return "std::vector<float>()" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK changed to error for stricter checking
No description provided.